package lan.core.io

import java.io._

trait IOAware {
  def execClose[A <: Closeable, B](c: A) (f: A => B):B = {
    try {
      return f(c)
    } finally {
      c.close
    }
  }
  
  def eachChunk[B](in: InputStream, buffer: Array[Byte])(func: (Array[Byte], Int) => B) = {
    if(buffer.size == 0) error("cannot use empty array as buffer")
    execClose(in) { _ => 
      var read = 0
      do {
        read = in.read(buffer)
        func(buffer, read)
      } while(read >= 0)
    }
  }
  
  class TransferSource(val in: InputStream) {
    private def doTransfer(out: OutputStream):Unit = {
      val buffer = new Array[byte](10240)
      var read = 0
      do {
        read = in.read(buffer)
        out.write(buffer, 0, read)
      } while(read >= 0)
    }
    
    def transferTo(out: OutputStream) = {
      execClose(out) { _ => 
        eachChunk(in, new Array[byte](10240)) { (b, max) => out.write(b, 0, max)}  
      }
    }
  }
  
  implicit def in2s (in: InputStream) = new TransferSource(in)
  
}
